﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Channels;
using System.Threading.Tasks;
using dbasyn.model;
using Mapster;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using Serilog;
using Serilog.Sinks.Loki;

namespace dbasyn
{
    public class Worker : BackgroundService
    {
        private readonly IConnection connection;
        private readonly IModel channel;
        private readonly ILogger loger;

        public Worker(ILogger _loger)
        {
            QuestDb quest = new QuestDb();
            loger = _loger;
            var factory = new ConnectionFactory();
            factory.HostName = "pod1"; //主机名，Rabbit会拿这个IP生成一个endpoint，这个很熟悉吧，就是socket绑定的那个终结点。
            factory.UserName = "lxbweixin"; //默认用户名,用户可以在服务端自定义创建，有相关命令行
            factory.Password = "lxbweixin"; //默认密码
            connection = factory.CreateConnection(); //连接服务器，即正在创建终结点。
            {
                channel = connection.CreateModel();
                {
                    Console.WriteLine("RabitmqClient 链接成功");
                    loger.Information(" dbasyn RabitmqClient 链接成功");
                    channel.QueueDeclare("canal_queue", true, false, false, null); //创建一个名称为kibaqueue的消息队列

                    var consumer = new EventingBasicConsumer(channel); //消费者
                    channel.BasicConsume("canal_queue", true, consumer); //消费消息
                    channel.BasicQos(0, 2, false);
                    consumer.Received += (model, ea) =>
                    {
                        try
                        {
                            var body = ea.Body;
                            var message = Encoding.UTF8.GetString(body.ToArray());

                            dynamic jsonObj = JsonConvert.DeserializeObject<dynamic>(message);
                            string type = jsonObj.type.ToString();
                            String table = jsonObj.table.ToString();
                            //  loger.Error($"{type} {table}  {message}");
                            switch (type)
                            {
                                case "INSERT":

                                    switch (table)
                                    {
                                        case "lxb_kaoqin_log":
                                            Console.WriteLine(
                                                DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")
                                            );
                                            //        global::System.Console.WriteLine(jsonObj.type);

                                            lxb_kaoqin_log kql =
                                                JsonConvert.DeserializeObject<lxb_kaoqin_log>(
                                                    jsonObj.data[0].ToString()
                                                );

                                            lxb_user userl = Mysql.getUser(kql.Id);
                                            if (userl != null)
                                            {
                                                kql.state = userl.state;
                                                kql.zhusu = userl.zschool;
                                                kql.slname = userl.slname;
                                                kql.banji = userl.clname;
                                                kql.wucan = userl.dx;
                                                kql.phone = userl.tel;
                                            }

                                            // Console.WriteLine(j.admin_name);
                                            quest.insert(kql);
                                            //Console.WriteLine(jsonObj.table);
                                            break;
                                        case "lxb_admin_log":
                                            // global::System.Console.WriteLine(jsonObj.data[0]);
                                            lxb_admin_log j =
                                                JsonConvert.DeserializeObject<lxb_admin_log>(
                                                    jsonObj.data[0].ToString()
                                                );
                                            // Console.WriteLine(j.admin_name);
                                            quest.insert(j);
                                            break;
                                        case "lxb_money":
                                            global::System.Console.WriteLine(jsonObj.data[0]);
                                            money m = JsonConvert.DeserializeObject<money>(
                                                jsonObj.data[0].ToString()
                                            );
                                            var lxbm = m.Adapt<lxb_money>();
                                            lxb_user user = Mysql.getUser(m.UID);
                                            var d = Mysql.getDev(m.SN);

                                            if (d != null)
                                            {
                                                lxbm.devname = d.Name;
                                                var tag = Mysql.getTag(d.tag);
                                                if (tag != null)
                                                {
                                                    lxbm.tagname = tag.Name;
                                                    lxbm.tag = tag.id;
                                                }
                                            }
                                            if (user != null)
                                            {
                                                lxbm.username = user.username;
                                                lxbm.School = user.slname;
                                                lxbm.classmate = user.clname;
                                                lxbm.state = user.state;
                                            }

                                            quest.insertMoney(lxbm);
                                            break;
                                        default:
                                            break;
                                    }

                                    break;
                                case "UPDATE":
                                    switch (table)
                                    {
                                        case "lxb_money":
                                            loger.Error(type + table + message);
                                            Dictionary<string, string> old =
                                                JsonConvert.DeserializeObject<
                                                    Dictionary<string, string>
                                                >(jsonObj.old[0].ToString());

                                            var ms = JsonConvert.DeserializeObject<List<money>>(
                                                jsonObj.data[0].ToString()
                                            );
                                            foreach (var m in ms)
                                            {
                                                if (old.ContainsKey("Tui"))
                                                {
                                                    loger.Error(
                                                        "update lxb_money set TUI = "
                                                            + m.TUI
                                                            + " where Id = "
                                                            + m.Id
                                                    );
                                                    quest.exec(
                                                        "update lxb_money set TUI = "
                                                            + m.TUI
                                                            + " where Id = "
                                                            + m.Id
                                                    );
                                                }
                                            }

                                            break;
                                        case "lxb_user":
                                            loger.Error($"{type} {table}  {message}");
                                            break;
                                        case "lxb_kaoqin_log":
                                             loger.Error(type + table + message);
                                            Dictionary<string, string> oldkq =
                                                JsonConvert.DeserializeObject<
                                                    Dictionary<string, string>
                                                >(jsonObj.old[0].ToString());

                                            IList<lxb_kaoqin_log> mskq = JsonConvert.DeserializeObject<List<lxb_kaoqin_log>>(
                                                jsonObj.data[0].ToString()
                                            );
                                            foreach (lxb_kaoqin_log m in mskq)
                                            {
                                                if (oldkq.ContainsKey("Tui"))
                                                {
                                                    loger.Error(
                                                        "update lxb_kaoqin_log set TUI = "
                                                            + m.phone
                                                            + " where Lid = "
                                                            + m.Lid
                                                    );
                                                    quest.exec(
                                                        "update lxb_kaoqin_log set photo = "
                                                            + m.phone
                                                            + " where Lid = "
                                                            + m.Lid
                                                    );
                                                }
                                            }
                                            break;
                                    }
                                    break;
                                case "DELETE":

                                    switch (table)
                                    {
                                        case "lxb_money":

                                            var ms = JsonConvert.DeserializeObject<List<money>>(
                                                jsonObj.data.ToString()
                                            );
                                            foreach (var m in ms)
                                            {
                                                var sql =
                                                    "update lxb_money set Isdel = true where Id = "
                                                    + m.Id;
                                                loger.Information(sql);
                                                quest.exec(sql);
                                            }

                                            break;
                                    }
                                    break;

                                default:

                                    break;
                            }
                        }
                        catch (Exception ex)
                        {
                            loger.Error(ex.ToString());
                            loger.Error(ex.StackTrace.ToString());

                            global::System.Console.WriteLine(ex.Message);
                        }
                    };
                }
            }
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                Console.WriteLine("dbasyn  connection  ?" + connection.IsOpen);

                await Task.Delay(1000 * 60 * 5, stoppingToken);
            }
            channel.Close();
            channel.Dispose();
            connection.Close();
            connection.Dispose();
        }
    }
}
